#include "led_list_ext.h"
// std-lib
#include <stdlib.h>
#include <string.h>
// lib
#include "debug.h"

#define pLed system_param.led_parm

#define SAFE_FREE(p_)                       do { if(p_) { MID_HEAP_FREE(p_); (p_)=NULL; }} while(0)     // 安全释放内存
#define IS_LIST_HEAD_UNINIT(_ptListHead)    ((_ptListHead)->ptHead.ptNext == NULL)

// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------

/// @brief 新增监测项数据
/// @param uNodeId 节点ID
/// @param uMonitorId 监测项ID
void create_monitor_data(uint32_t uNodeId, uint32_t uMonitorId) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return;
    }
    mntr_parm_t *ptMonitorData = (mntr_parm_t *)MID_HEAP_MALLOC(sizeof(mntr_parm_t));
    memset(ptMonitorData, 0, sizeof(mntr_parm_t));
    ptMonitorData->uServerId = uMonitorId;
    if (IS_LIST_HEAD_UNINIT(&ptNodeData->tMntrListHead)) {      // 检查此链表是否初始化
        list_init(&ptNodeData->tMntrListHead);
    }
    list_add_end(&ptNodeData->tMntrListHead, ptMonitorData);    // 将新节点添加到链表末尾
}

/// @brief 删除监测项数据
/// @param uNodeId 节点ID
/// @param uMonitorId 监测项ID
void delete_monitor_data(uint32_t uNodeId, uint32_t uMonitorId) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return;
    }
    mntr_parm_t *ptMonitorData = select_monitor_data(uNodeId, uMonitorId);
    if (ptMonitorData == NULL) {
        return;
    }
    SAFE_FREE(ptMonitorData->pName);
    SAFE_FREE(ptMonitorData->pUnit);
    SAFE_FREE(ptMonitorData->pCode);
    list_delete_node(&ptNodeData->tMntrListHead, ptMonitorData);
}

/// @brief 删除对应节点的所有监测项数据
/// @param uNodeId 节点ID
void delete_all_monitor_data_by_node_p(node_parm_t *ptNodeData) {
    if (ptNodeData == NULL) {
        return;
    }
    mntr_parm_t *ptMonitorData;
    LIST_TRAVERSE(&ptNodeData->tMntrListHead, ptMonitorData) {
        SAFE_FREE(ptMonitorData->pName);
        SAFE_FREE(ptMonitorData->pUnit);
        SAFE_FREE(ptMonitorData->pCode);
        SAFE_FREE(ptMonitorData);
    }
    list_delete_all_node(&ptNodeData->tMntrListHead);
}

/// @brief 删除对应节点的所有监测项数据
/// @param uNodeId 节点ID
void delete_all_monitor_data_by_node_id(uint32_t uNodeId) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return;
    }
    delete_all_monitor_data_by_node_p(ptNodeData);
}

/// @brief 修改监测项数据
/// @param uNodeId 节点ID
/// @param uMonitorId 监测项ID
/// @param tMonitorData 监测项数据结构
void update_monitor_data(uint32_t uNodeId, uint32_t uMonitorId, mntr_parm_t tMonitorData) {
    mntr_parm_t *ptMonitorData = select_monitor_data(uNodeId, uMonitorId);
    if (ptMonitorData == NULL) {
        return;
    }
    // 清除旧数据
    SAFE_FREE(ptMonitorData->pName);
    SAFE_FREE(ptMonitorData->pUnit);
    SAFE_FREE(ptMonitorData->pCode);
    // 设置新数据
    memcpy(ptMonitorData, &tMonitorData, sizeof(mntr_parm_t));
}

/// @brief 获取监测项数据
/// @param uNodeId 节点ID
/// @param uMonitorId 监测项ID
/// @return mntr_parm_t* 成功则返回监测项数据结构指针，失败则返回NULL
mntr_parm_t *select_monitor_data(uint32_t uNodeId, uint32_t uMonitorId) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return NULL;
    }
    mntr_parm_t *ptMonitorData;
    LIST_TRAVERSE(&ptNodeData->tMntrListHead, ptMonitorData) {
        if (uMonitorId == ptMonitorData->uServerId) {
            return ptMonitorData;
        }
    }
    return NULL;
}



/// @brief 新增节点数据
/// @param uNodeId 节点ID
void create_node_data(uint32_t uNodeId) {
    node_parm_t *ptNodeData = (node_parm_t *)MID_HEAP_MALLOC(sizeof(node_parm_t));
    memset(ptNodeData, 0, sizeof(node_parm_t));
    ptNodeData->uServerId = uNodeId;
    list_add_end(&pLed.tNodeListHead, ptNodeData); // 将新节点添加到链表末尾
}

/// @brief 删除节点数据
/// @param uNodeId 节点ID
void delete_node_data(uint32_t uNodeId) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return;
    }
    SAFE_FREE(ptNodeData->pName);
    delete_all_monitor_data_by_node_p(ptNodeData); // 删除监测项
    list_delete_node(&pLed.tNodeListHead, ptNodeData);
}

/// @brief 删除所有节点数据
void delete_all_node_data(void) {
    node_parm_t *ptNodeData;
    LIST_TRAVERSE(&pLed.tNodeListHead, ptNodeData) {
        SAFE_FREE(ptNodeData->pName);
        // 还需要检查下一级链表是否有需要释放的资源
        if (ptNodeData->tMntrListHead.iListLen != 0) {
            delete_all_monitor_data_by_node_p(ptNodeData);
        }
        SAFE_FREE(ptNodeData);
    }
    list_delete_all_node(&pLed.tNodeListHead);
}

/// @brief 修改节点数据
/// @param uNodeId 节点ID
/// @param tNodeData 节点数据结构
void update_node_data(uint32_t uNodeId, node_parm_t tNodeData) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return;
    }
    // 清除旧数据
    SAFE_FREE(ptNodeData->pName);
    // 如果已经初始化，则复制此项数据
    if (!IS_LIST_HEAD_UNINIT(&tNodeData.tMntrListHead)) {
        memcpy(&tNodeData.tMntrListHead, &ptNodeData->tMntrListHead, sizeof(list_base_t));
    }
    // 设置新数据
    memcpy(ptNodeData, &tNodeData, sizeof(node_parm_t));
}

/// @brief 获取节点数据
/// @param uNodeId 节点ID
/// @return node_parm_t * 成功时返回节点数据结构，失败时返回NULL
node_parm_t *select_node_data(uint32_t uNodeId) {
    node_parm_t *ptNodeData = NULL;
    LIST_TRAVERSE(&pLed.tNodeListHead, ptNodeData) {
        if (ptNodeData->uServerId == uNodeId) {
            return ptNodeData;
        }
    }
    return NULL;
}

/// @brief 更新所以节点数据的周期计数器
/// @return true 有一个或以上节点数据需要更新 false 没有节点数据需要更新
bool update_all_node_cycle_cnt(void) {
    bool bRet = false;
    node_parm_t *ptNodeData = NULL;
    LIST_TRAVERSE(&pLed.tNodeListHead, ptNodeData) {
        if (ptNodeData->uCycle != 0) {
            ptNodeData->uMinCnt++;                              // 周期计数器自增
            if (ptNodeData->uMinCnt >= ptNodeData->uCycle) {
                bRet = true;
                ptNodeData->uMinCnt = 0;                        // 周期计数器清零
                ptNodeData->bUpdateData = false;                // 标记需要更新数据
            }
        }
    }
    return bRet;
}



/// @brief 设置LED参数
/// @param uLedId LED的服务器ID
/// @param ptsLedName LED的名称
/// @return int32_t <0-fail, >=0-success
int32_t set_led_parm(uint32_t uLedId, char *ptsLedName, uint32_t LedNameLen) {
    list_init(&pLed.tNodeListHead);         // 初始化链表
    pLed.uServerId = uLedId;
    if (LedNameLen > LED_NAME_MAX_LEN) {    // 名称长度超出限制
        return -1;
    }
    if (ptsLedName == NULL) {               // 名称为空指针
        return -2;
    }
    SAFE_FREE(pLed.pName);        // 释放旧数据
    pLed.pName = (char *)MID_HEAP_MALLOC(LedNameLen + 1);
    if (pLed.pName == NULL) {               // 内存分配失败
        return -3;
    }
    memset(pLed.pName, 0, LedNameLen + 1);
    strcpy(pLed.pName, ptsLedName);
    return 0; // 设置成功
}

/// @brief 获取节点总数
/// @return 节点总数
uint32_t get_led_node_sum(void) {
    return pLed.tNodeListHead.iListLen;
}

/// @brief 获取节点对应监测项总数
/// @param uNodeId 节点ID
/// @return 监测项总数
uint32_t get_led_monitor_sum(uint32_t uNodeId) {
    return select_node_data(uNodeId)->tMntrListHead.iListLen;
}

/// @brief 根据序号获取节点ID
/// @param uNodeIndex 节点序号
/// @return 节点ID
uint32_t get_led_node_id_by_num(uint32_t uNodeIndex) {
    node_parm_t *ptNodeData = list_get_node_by_num(&pLed.tNodeListHead, uNodeIndex);
    if (ptNodeData == NULL) {
        return 0; // 节点不存在
    } else {
        return ptNodeData->uServerId;
    }
}

/// @brief 根据序号获取监测项ID
/// @param uNodeId 节点ID
/// @param uMonitorIndex 监测项序号
/// @return 节点ID
uint32_t get_led_monitor_id_by_num(uint32_t uNodeId, uint32_t uMonitorIndex) {
    node_parm_t *ptNodeData = select_node_data(uNodeId);
    if (ptNodeData == NULL) {
        return 0; // 节点不存在
    } else {
        mntr_parm_t *ptMonitorData = list_get_node_by_num(&ptNodeData->tMntrListHead, uMonitorIndex);
        if (ptMonitorData == NULL) {
            return 0; // 监测项不存在
        } else {
            return ptMonitorData->uServerId;
        }
    }
}
